{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "transfer-learning.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "toc_visible": true,
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/lmoroney/tfbook/blob/master/chapter3/transfer_learning.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zX4Kg8DUTKWO",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "ioLbtB3uGKPX",
        "colab": {}
      },
      "source": [
        "try:\n",
        "  # %tensorflow_version only exists in Colab.\n",
        "  %tensorflow_version 2.x\n",
        "except Exception:\n",
        "  pass"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "y23ucAFLoHop",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import urllib.request\n",
        "import os\n",
        "import zipfile\n",
        "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
        "from tensorflow.keras import layers\n",
        "from tensorflow.keras import Model\n",
        "from tensorflow.keras.applications.inception_v3 import InceptionV3\n",
        "from tensorflow.keras.optimizers import RMSprop\n",
        "\n",
        "weights_url = \"https://storage.googleapis.com/mledu-datasets/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5\"\n",
        "weights_file = \"inception_v3.h5\"\n",
        "urllib.request.urlretrieve(weights_url, weights_file)\n",
        "\n",
        "pre_trained_model = InceptionV3(input_shape=(150, 150, 3),\n",
        "                                include_top=False,\n",
        "                                weights=None)\n",
        "\n",
        "pre_trained_model.load_weights(weights_file)\n",
        "\n",
        "for layer in pre_trained_model.layers:\n",
        "    layer.trainable = False\n",
        "\n",
        "# pre_trained_model.summary()\n",
        "\n",
        "last_layer = pre_trained_model.get_layer('mixed7')\n",
        "print('last layer output shape: ', last_layer.output_shape)\n",
        "last_output = last_layer.output\n",
        "\n",
        "# Flatten the output layer to 1 dimension\n",
        "x = layers.Flatten()(last_output)\n",
        "# Add a fully connected layer with 1,024 hidden units and ReLU activation\n",
        "x = layers.Dense(1024, activation='relu')(x)\n",
        "# Add a dropout rate of 0.2\n",
        "x = layers.Dropout(0.2)(x)\n",
        "# Add a final sigmoid layer for classification\n",
        "x = layers.Dense(1, activation='sigmoid')(x)\n",
        "\n",
        "model = Model(pre_trained_model.input, x)\n",
        "\n",
        "model.compile(optimizer=RMSprop(lr=0.0001),\n",
        "              loss='binary_crossentropy',\n",
        "              metrics=['acc'])\n",
        "\n",
        "training_url = \"https://storage.googleapis.com/learning-datasets/horse-or-human.zip\"\n",
        "training_file_name = \"horse-or-human.zip\"\n",
        "training_dir = 'horse-or-human/training/'\n",
        "urllib.request.urlretrieve(training_url, training_file_name)\n",
        "zip_ref = zipfile.ZipFile(training_file_name, 'r')\n",
        "zip_ref.extractall(training_dir)\n",
        "zip_ref.close()\n",
        "\n",
        "validation_url = \"https://storage.googleapis.com/learning-datasets/validation-horse-or-human.zip\"\n",
        "validation_file_name = \"validation-horse-or-human.zip\"\n",
        "validation_dir = 'horse-or-human/validation/'\n",
        "urllib.request.urlretrieve(validation_url, validation_file_name)\n",
        "\n",
        "zip_ref = zipfile.ZipFile(validation_file_name, 'r')\n",
        "zip_ref.extractall(validation_dir)\n",
        "zip_ref.close()\n",
        "\n",
        "\n",
        "# Add our data-augmentation parameters to ImageDataGenerator\n",
        "train_datagen = ImageDataGenerator(rescale=1./255.,\n",
        "                                   rotation_range=40,\n",
        "                                   width_shift_range=0.2,\n",
        "                                   height_shift_range=0.2,\n",
        "                                   shear_range=0.2,\n",
        "                                   zoom_range=0.2,\n",
        "                                   horizontal_flip=True)\n",
        "\n",
        "# Note that the validation data should not be augmented!\n",
        "test_datagen = ImageDataGenerator(rescale=1.0/255.)\n",
        "\n",
        "# Flow training images in batches of 20 using train_datagen generator\n",
        "train_generator = train_datagen.flow_from_directory(training_dir,\n",
        "                                                    batch_size=20,\n",
        "                                                    class_mode='binary',\n",
        "                                                    target_size=(150, 150))\n",
        "\n",
        "# Flow validation images in batches of 20 using test_datagen generator\n",
        "validation_generator =  test_datagen.flow_from_directory(validation_dir,\n",
        "                                                         batch_size=20,\n",
        "                                                         class_mode='binary',\n",
        "                                                         target_size=(150, 150))\n",
        "\n",
        "\n",
        "history = model.fit_generator(\n",
        "            train_generator,\n",
        "            validation_data=validation_generator,\n",
        "            epochs=20,\n",
        "            verbose=1)\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "DoWp43WxJDNT",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "import numpy as np\n",
        "from google.colab import files\n",
        "from keras.preprocessing import image\n",
        "\n",
        "uploaded = files.upload()\n",
        "\n",
        "for fn in uploaded.keys():\n",
        " \n",
        "  # predicting images\n",
        "  path = '/content/' + fn\n",
        "  img = image.load_img(path, target_size=(150, 150))\n",
        "  x = image.img_to_array(img)\n",
        "  x = np.expand_dims(x, axis=0)\n",
        "\n",
        "  image_tensor = np.vstack([x])\n",
        "  classes = model.predict(image_tensor)\n",
        "  print(classes)\n",
        "  print(classes[0])\n",
        "  if classes[0]>0.5:\n",
        "    print(fn + \" is a human\")\n",
        "  else:\n",
        "    print(fn + \" is a horse\")\n",
        " "
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}
